package com.zhixing.service.processor;

import com.zhixing.common.ISwaggerConstants;
import com.zhixing.model.SwaggerDefinitionModelAttr;
import com.zhixing.model.SwaggerRequest;
import com.zhixing.utils.JsonUtils;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * swagger 入参 json 解析处理器
 * @author zhixing
 */
public class SwaggerRequestParamProcessor implements SwaggerProcessor{
    /** json 解析后的 入参对象 **/
    @Getter
    private StringBuffer            resultStr;

    @Getter
    private List<SwaggerRequest>    requestList;

    private SwaggerRequestParamProcessor(){
        this.resultStr = new StringBuffer();
    }

    public static Builder createBuild(){
        return  new Builder();
    }

    public static class Builder{
        private SwaggerRequestParamProcessor processor;
        public Builder(){
            this.processor = new SwaggerRequestParamProcessor();
        }

        public Builder requestList(List<SwaggerRequest> requestList){
            this.processor.requestList = requestList;
            return this;
        }

        public SwaggerRequestParamProcessor build(){
            return this.processor;
        }

    }

    @Override
    public SwaggerRequestParamProcessor process() throws IOException {
        doProcess();
        return this;
    }

    /**
     * 处理请求参数列表
     *
     * @return
     */
    private void doProcess() throws IOException{
        Map<String, Object> headerMap = new LinkedHashMap<>();
        Map<String, Object> queryMap = new LinkedHashMap<>();
        Map<String, Object> jsonMap = new LinkedHashMap<>();
        if (!CollectionUtils.isEmpty(requestList)) {
            for (SwaggerRequest request : requestList) {
                String name = request.getName();
                String paramType = request.getParamType();
                Object value = getValue(request.getType(), request.getModelAttr());
                switch (paramType) {
                    case ISwaggerConstants.IPATHS.IPARAMETERS.IIN.HEADER:
                        headerMap.put(name, value);
                        break;
                    case ISwaggerConstants.IPATHS.IPARAMETERS.IIN.QUERY:
                        queryMap.put(name, value);
                        break;
                    case ISwaggerConstants.IPATHS.IPARAMETERS.IIN.BODY:
                        jsonMap.put(name, value);
                        break;
                    default:
                        break;

                }
            }
        }


        if (!queryMap.isEmpty()) {
            resultStr.append(getUrlParamsByMap(queryMap));
        }
        if (!headerMap.isEmpty()) {
            resultStr.append(getHeaderByMap(headerMap));
        }
        if (!jsonMap.isEmpty()) {
            if (jsonMap.size() == 1) {
                for (Map.Entry<String, Object> entry : jsonMap.entrySet()) {
                    resultStr.append(" -d '")
                            .append(JsonUtils.writeJsonStr(entry.getValue()))
                            .append("'");
                }
            } else {
                resultStr.append(" -d '")
                        .append(JsonUtils.writeJsonStr(jsonMap))
                        .append("'");
            }
        }
    }

    /**
     * 例子中，字段的默认值
     *
     * @param type      类型
     * @param modelAttr 引用的类型
     * @return
     */
    protected Object getValue(String type, SwaggerDefinitionModelAttr modelAttr) {
        int pos;
        if ((pos = type.indexOf(":")) != -1) {
            type = type.substring(0, pos);
        }
        switch (type) {
            case ISwaggerConstants.IDATA_TYPE.STRING:
                return "string";
            case ISwaggerConstants.IDATA_TYPE.STRING_DATE:
                return 123456789;
            case ISwaggerConstants.IDATA_TYPE.INTEGER:
            case ISwaggerConstants.IDATA_TYPE.INTEGER_64:
            case ISwaggerConstants.IDATA_TYPE.INTEGER_32:
                return 0;
            case ISwaggerConstants.IDATA_TYPE.NUMBER:
                return 0.0;
            case ISwaggerConstants.IDATA_TYPE.BOOLEAN:
                return true;
            case ISwaggerConstants.IDATA_TYPE.FILE:
                return "(binary)";
            case ISwaggerConstants.IDATA_TYPE.ARRAY:
                List list = new ArrayList();
                Map<String, Object> map = new LinkedHashMap<>();
                if (modelAttr != null && !CollectionUtils.isEmpty(modelAttr.getProperties())) {
                    for (SwaggerDefinitionModelAttr subModelAttr : modelAttr.getProperties()) {
                        map.put(subModelAttr.getName(), getValue(subModelAttr.getType(), subModelAttr));
                    }
                }
                list.add(map);
                return list;
            case ISwaggerConstants.IDATA_TYPE.OBJECT:
                map = new LinkedHashMap<>();
                if (modelAttr != null && !CollectionUtils.isEmpty(modelAttr.getProperties())) {
                    for (SwaggerDefinitionModelAttr subModelAttr : modelAttr.getProperties()) {
                        map.put(subModelAttr.getName(), getValue(subModelAttr.getType(), subModelAttr));
                    }
                }
                return map;
            default:
                return null;
        }
    }

    /**
     * 将map转换成url
     */
    public static String getUrlParamsByMap(Map<String, Object> map) {
        if (CollectionUtils.isEmpty(map)) {
            return "";
        }
        StringBuilder sBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sBuilder.append(entry.getKey() + "=" + entry.getValue());
            sBuilder.append("&");
        }
        String s = sBuilder.toString();
        if (s.endsWith("&")) {
            s = StringUtils.substringBeforeLast(s, "&");
        }
        return s;
    }

    /**
     * 将map转换成header
     */
    public static String getHeaderByMap(Map<String, Object> map) {
        if (CollectionUtils.isEmpty(map)) {
            return "";
        }
        StringBuilder sBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sBuilder.append("--header '");
            sBuilder.append(entry.getKey() + ":" + entry.getValue());
            sBuilder.append("'");
        }
        return sBuilder.toString();
    }
}
